package cz.stv.pecinovsky.město;

import cz.stv.pecinovsky.správceplátna.Přesouvač;
import cz.stv.pecinovsky.správceplátna.SprávcePlátna;

import cz.stv.pecinovsky.utility.Barva;
import cz.stv.pecinovsky.utility.IO;
import cz.stv.pecinovsky.utility.Pozice;

import java.util.ArrayList;
import java.util.List;


/*******************************************************************************
 * Testovací třída {@code SvětloTest}  slouží ke komplexnímu otestování
 * třídy {@link SvětloTest}.
 *
 * @author  Rudolf PECINOVSKÝ
 * @version 1.10.2678 — 2011-10-27
 */
public class SvětloTest extends junit.framework.TestCase
{
    private SprávcePlátna SP;
    private Světlo světlo0;
    private Světlo světloXY;
    private Světlo světloXYB;
    private Světlo světloXYP;
    private Světlo světloXYPB;
    private Světlo světloXYPBZ;



//== KONSTANTNÍ ATRIBUTY TŘÍDY =================================================
//== PROMĚNNÉ ATRIBUTY TŘÍDY ===================================================
//== STATICKÝ INICIALIZAČNÍ BLOK - STATICKÝ KONSTRUKTOR ========================
//== KONSTANTNÍ ATRIBUTY INSTANCÍ ==============================================
//== PROMĚNNÉ ATRIBUTY INSTANCÍ ================================================
//== PŘÍSTUPOVÉ METODY VLASTNOSTÍ TŘÍDY ========================================
//== OSTATNÍ NESOUKROMÉ METODY TŘÍDY ===========================================

//##############################################################################
//== KONSTRUKTORY A TOVÁRNÍ METODY =============================================

    /***************************************************************************
     * Vytvoří test se zadaným názvem.
     *
     * @param název  Název konstruovaného testu
     */
    public SvětloTest( String název )
    {
        super(název);
    }



//== PŘÍPRAVA A ÚKLID PŘÍPRAVKU ================================================

    /***************************************************************************
     * Inicializace předcházející spuštění každého testu a připravující tzv.
     * přípravek (fixture), což je sada objektů, s nimiž budou testy pracovat.
     */
    @Override
    protected void setUp()
    {
        světlo0    = new Světlo();
        světloXY   = new Světlo( 50,  50);
        světloXYB  = new Světlo(100, 100, Barva.ČERVENÁ);
        světloXYP  = new Světlo(  0, 100, 100);
        světloXYPB = new Světlo(100,   0, 100, Barva.MODRÁ);
        světloXYPBZ= new Světlo(150, 150, 150, Barva.FIALOVÁ, Barva.ŽÁDNÁ);

        SP = SprávcePlátna.getInstance();
        SP.přidej(světlo0);
        SP.přidej(světloXY);
        SP.přidej(světloXYB);
        SP.přidej(světloXYP);
        SP.přidej(světloXYPB);
        SP.přidej(světloXYPBZ);

        System.out.println("\n====== Instance v přípravku pro " + this +
                           "\n| SP: " + SP +
                           "\n| světlo0:    " + světlo0 +
                           "\n| světloXY:   " + světloXY +
                           "\n| světloXYB:  " + světloXYB +
                           "\n| světloXYM : " + světloXYP +
                           "\n| světloXYMB: " + světloXYPB +
                           "\n| světloXYMB: " + světloXYPBZ +
                           "\n======");
        IO.zpráva("Světla připravena");
    }


    /***************************************************************************
     * Úklid po testu - tato metoda se spustí po vykonání každého testu.
     */
    @Override
    protected void tearDown()
    {
    }


//== SOUKROMÉ A POMOCNÉ METODY TŘÍDY ===========================================
//== SOUKROMÉ A POMOCNÉ METODY INSTANCÍ ========================================

    /***************************************************************************
     * Prohodí pozice zadaných světel a nechá zkontrolovat,
     * zda si světla své pozice doopravdy vyměnila.
     *
     * @param s1 První světlo
     * @param s2 Druhé světlo
     */
    private void pomProhoďPozice(Světlo s1, Světlo s2)
    {
        final int ms = 1000;

        s1.zhasni();
        s2.zhasni();
        IO.čekej(ms);

        Pozice p1 = s1.getPozice();
        s1.setPozice(s2.getPozice());
        s2.setPozice(p1);

        IO.čekej(ms);
        s1.rozsviť();
        s2.rozsviť();

        IO.čekej(ms);
    }



//== INTERNÍ DATOVÉ TYPY =======================================================
//== VLASTNÍ TESTY =============================================================
//
//     /***************************************************************************
//      *
//      */
//     public void testXXX()
//     {
//     }


    public void testBlikni()
    {
        světlo0    .zhasni();
        světloXY   .zhasni();
        světloXYB  .zhasni();
        světloXYP  .zhasni();
        světloXYPB .zhasni();
        světloXYPBZ.zhasni();
        IO.čekej(500);
        světlo0    .blikni();
        světloXY   .blikni();
        světloXYB  .blikni();
        světloXYP  .blikni();
        světloXYPB .blikni();
        světloXYPBZ.blikni();
        IO.čekej(500);
        světlo0    .rozsviť();
        světloXY   .rozsviť();
        světloXYB  .rozsviť();
        světloXYP  .rozsviť();
        světloXYPB .rozsviť();
        světloXYPBZ.rozsviť();
    }


    public void testPlynuléPosuny()
    {
        Přesouvač p = new Přesouvač(10);
        p.přesunNa(200,   0, světlo0);
        p.přesunNa(200,  50, světloXY);
        p.přesunNa(  0,   0, světloXYPBZ);
        p.přesunNa(200, 100, světloXYPB);
        p.přesunNa(150,   0, světloXYB);
        p.přesunNa(  0, 150, světloXYP);
    }


    public void testPoziceVelikost()
    {
        Pozice sem = new Pozice(0, 150);
        int malý   = 25;
        int velký  = 150;

        TestUtility.poziceVelikost(světloXYPBZ, sem, malý, velký);
        TestUtility.poziceVelikost(světloXYPB,  sem, malý, velký);
        TestUtility.poziceVelikost(světloXYP,   sem, malý, velký);
        TestUtility.poziceVelikost(světloXYB,   sem, malý, velký);
        TestUtility.poziceVelikost(světloXY,    sem, malý, velký);
        TestUtility.poziceVelikost(světlo0,     sem, malý, velký);
    }


    public void testGetBarva()
    {
        assertEquals(Barva.MODRÁ, světloXYPB.getBarva());
        assertEquals(Barva.MODRÁ, světlo0.getBarva());
    }


    public void testProhoďPozice()
    {
        pomProhoďPozice(světlo0,   světloXYPB);
        pomProhoďPozice(světloXYB, světloXYP);
        pomProhoďPozice(světloXYP, světlo0);
    }


    public void testProhoďPoziceSKontrolou()
    {
        TestUtility.prohoďPoziceSKontrolou(světlo0,   světloXYPB);
        TestUtility.prohoďPoziceSKontrolou(světloXYB, světloXYP);
        TestUtility.prohoďPoziceSKontrolou(světloXYP, světlo0);
    }


    /***************************************************************************
     * Vyzkouší schopnosti komparátoru ve třídě {@link TestUtility}
     * při řazení světel.
     */
    public void testSeřaďSeznam()
    {
        List<IModulový> seznam = new ArrayList<IModulový>();
        seznam.add(světlo0);
        seznam.add(světloXY);
        seznam.add(světloXYB);
        seznam.add(světloXYP);
        seznam.add(světloXYPB);
        seznam.add(světloXYPBZ);
        seznam.add(světlo0);
        TestUtility.seřaďSeznam(seznam);
    }

}
